package utils ;

import java.io.File ;
import java.io.FileInputStream ;
import java.io.FileOutputStream ;
import java.io.IOException ;
import java.util.List ;

import org.apache.commons.net.ftp.FTPClient ;
import org.slf4j.Logger ;
import org.slf4j.LoggerFactory ;

/**
 * 使用jakarta commons中的FTPClient工具类，实现向FTP上传，下载等操作文件的方法
 * @author 80002165 @date 2017年8月3日 下午4:50:16
 */
public class FTPUtil {
    private static final Logger logger = LoggerFactory.getLogger(FTPUtil.class) ;
    
    // ftp服务地址
    private String ftpUrl ;
    // ftp服务器端口
    private int ftpPort ;
    // 登录ftp服务用户名和密码
    private String ftpUser ;
    private String ftpPassword ;
    
    private FTPClient ftpClient ;
    private static int ftp_buffer_size = 1024 ;
    
    public FTPUtil(String ftpUrl, int ftpPort, String ftpUser, String ftpPassword) {
        super() ;
        this.ftpUrl = ftpUrl ;
        this.ftpPort = ftpPort ;
        this.ftpUser = ftpUser ;
        this.ftpPassword = ftpPassword ;
    }
    
    /**
     * 上传文件
     * @author 80002165 @date 2017年8月3日 下午5:56:46
     * @param remoteDir
     *        远程ftp目录
     * @param fileList
     *        文件列表
     * @return
     */
    public boolean upload(String remoteDir, List<File> fileList) {
        FileInputStream fis = null ;
        boolean uploaded = true ;
        if (connectFtp(this.ftpUrl, this.ftpPort, this.ftpUser, this.ftpPassword)) {
            // 设置编码
            ftpClient.setControlEncoding("UTF-8") ;
            // 设置缓冲大小
            ftpClient.setBufferSize(ftp_buffer_size) ;
            
            try {
                // 设置文件类型（二进制）
                ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE) ;
                // 更改fpt工作目录
                ftpClient.changeWorkingDirectory(remoteDir) ;
                
                for (int i = 0; i < fileList.size(); i++) {
                    File fileItem = fileList.get(i) ;
                    fis = new FileInputStream(fileItem) ;
                    ftpClient.storeFile(fileItem.getName(), fis) ;
                }
            } catch (IOException e) {
                logger.error("ftp上传文件异常！", e) ;
                uploaded = false ;
            } finally {
                try {
                    if (fis != null)
                        fis.close() ;
                    if (ftpClient != null)
                        ftpClient.disconnect() ;
                } catch (IOException e) {
                    logger.error("ftp上传文件释放资源异常！", e) ;
                }
            }
        }
        return uploaded ;
    }
    
    /**
     * ftp下载文件
     * @author 80002165 @date 2017年8月4日 下午2:22:18
     * @param remoteDir
     *        ftp服务文件目录
     * @param filePath
     *        ftp服务器文件名
     * @param destFileName
     *        下载后文件存储的路径
     */
    public boolean downloadFile(String remoteDir, String filePath, String destFileName) {
        FileOutputStream fos = null ;
        boolean downloaded = false ;
        if (connectFtp(this.ftpUrl, this.ftpPort, this.ftpUser, this.ftpPassword)) {
            try {
                ftpClient = initFTPClient(ftpClient) ;
                // 更改ftp工作目录
                ftpClient.changeWorkingDirectory(remoteDir) ;
                fos = new FileOutputStream(new File(destFileName)) ;
                ftpClient.retrieveFile(filePath, fos) ;
                downloaded = true ;
            } catch (IOException e) {
                logger.error("ftp服务下载文件异常！", e) ;
                
            } finally {
                try {
                    if (fos != null)
                        fos.close() ;
                    if (ftpClient != null)
                        ftpClient.disconnect() ;
                } catch (Exception e2) {
                    logger.error("ftp服务下载文件，释放资源异常！", e2) ;
                }
                
            }
        }
        return downloaded ;
    }
    
    public boolean rename(String remoteDir, String oldName, String newName) {
        boolean renamed = false ;
        if (connectFtp(this.ftpUrl, this.ftpPort, this.ftpUser, this.ftpPassword)) {
            try {
                ftpClient = initFTPClient(ftpClient) ;
                ftpClient.changeWorkingDirectory(remoteDir) ;
                ftpClient.rename(oldName, newName) ;
                renamed = true ;
            } catch (IOException e) {
                logger.error("ftp服务文件重命名异常！", e) ;
            } finally {
                closeFtpClient(ftpClient, "ftp服务文件重命名") ;
            }
        }
        return renamed ;
    }
    
    /**
     * 删除ftp文件
     * @author 80002165 @date 2017年8月4日 下午2:37:33
     * @param remoteDir
     *        远程目录
     * @param fileName
     *        删除的文件名
     * @return
     */
    public boolean remove(String remoteDir, String fileName) {
        boolean removed = false ;
        if (connectFtp(this.ftpUrl, this.ftpPort, this.ftpUser, this.ftpPassword)) {
            try {
                ftpClient = initFTPClient(ftpClient) ;
                ftpClient.changeWorkingDirectory(remoteDir) ;
                ftpClient.deleteFile(fileName) ;
                removed = true ;
            } catch (IOException e) {
                logger.error("ftp服务删除文件异常！", e) ;
                removed = false ;
            } finally {
                closeFtpClient(ftpClient, "ftp服务删除文件") ;
            }
        }
        return removed ;
    }
    
    /**
     * 创建目录
     * @author 80002165 @date 2017年8月4日 下午2:45:15
     * @param remoteDir
     * @param newDirtctory
     * @return
     */
    public boolean makeDirecotory(String remoteDir, String newDirtctory) {
        boolean maked = false ;
        if (connectFtp(this.ftpUrl, this.ftpPort, this.ftpUser, this.ftpPassword)) {
            try {
                ftpClient = initFTPClient(ftpClient) ;
                ftpClient.changeWorkingDirectory(remoteDir) ;
                ftpClient.makeDirectory(newDirtctory) ;
                maked = true ;
            } catch (IOException e) {
                logger.error("ftp服务新建目录异常！", e) ;
            } finally {
                closeFtpClient(ftpClient, "ftp服务新建目录") ;
            }
        }
        return maked ;
    }
    
    /**
     * 修改远程目录名
     * @author 80002165 @date 2017年8月4日 下午2:48:52
     * @param remoteDir
     * @param oldDirtctory
     * @param newDirectory
     * @return
     */
    public boolean renameDirecotory(String remoteDir, String oldDirtctory, String newDirectory) {
        boolean renamed = false ;
        if (connectFtp(this.ftpUrl, this.ftpPort, this.ftpUser, this.ftpPassword)) {
            try {
                ftpClient = initFTPClient(ftpClient) ;
                ftpClient.changeWorkingDirectory(remoteDir) ;
                ftpClient.rename(oldDirtctory, newDirectory) ;
                renamed = true ;
            } catch (IOException e) {
                logger.error("ftp服务重命名目录异常！", e) ;
            } finally {
                closeFtpClient(ftpClient, "ftp服务重命名目录") ;
            }
        }
        return renamed ;
    }
    
    /**
     * 测试ftp服务器是否可连接
     * @author 80002165 @date 2017年8月3日 下午5:27:30
     * @return true ftp服务器可以连接 ； false ftp服务器连接失败
     */
    public boolean connectFtp(String ftpUrl, int ftpPort, String ftpUser, String ftpPassword) {
        boolean canConnected = false ;
        ftpClient = new FTPClient() ;
        try {
            ftpClient.connect(ftpUrl, ftpPort) ;
            canConnected = ftpClient.login(ftpUser, ftpPassword) ;
        } catch (IOException e) {
            logger.error("连接FTP服务器异常！", e) ;
        }
        return canConnected ;
    }
    
    /**
     * ftp删除目录
     * @author 80002165 @date 2017年8月4日 下午2:54:56
     * @param remoteDir
     * @param dirtctory
     * @return
     */
    public boolean removeDirecotory(String remoteDir, String dirtctory) {
        boolean removed = false ;
        if (connectFtp(this.ftpUrl, this.ftpPort, this.ftpUser, this.ftpPassword)) {
            try {
                ftpClient = initFTPClient(ftpClient) ;
                ftpClient.changeWorkingDirectory(remoteDir) ;
                ftpClient.removeDirectory(dirtctory) ;
                removed = true ;
            } catch (IOException e) {
                logger.error("ftp服务删除目录异常！", e) ;
            } finally {
                closeFtpClient(ftpClient, "ftp服务删除目录") ;
            }
        }
        return removed ;
    }
    
    /**
     * 初始化FTPClient对象
     * @author 80002165 @date 2017年8月4日 下午2:24:44
     * @param ftpClient
     * @return
     * @throws IOException
     */
    private FTPClient initFTPClient(FTPClient ftpClient) throws IOException {
        if (ftpClient != null) {
            // 设置编码
            ftpClient.setControlEncoding("UTF-8") ;
            // 设置缓冲大小
            ftpClient.setBufferSize(ftp_buffer_size) ;
            // 设置文件类型
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE) ;
            
            ftpClient.enterLocalPassiveMode() ;
        }
        return ftpClient ;
    }
    
    private void closeFtpClient(FTPClient ftpClient, String msg) {
        try {
            if (ftpClient != null)
                ftpClient.disconnect() ;
        } catch (IOException e) {
            logger.error(msg + "释放资源异常！", e) ;
        }
    }
}
